 //
//  SummaryMgr.m
//  CarCare
//
//  Created by ileo on 15/4/9.
//  Copyright (c) 2015年 baozun. All rights reserved.
//

#import "SummaryMgr.h"
#import "NetHome.h"
#import "CalendarMgr.h"
#import "AILDSummary.h"

@implementation SummaryModel

@end

@interface SummaryMgr()<TriggerVister>

@property (nonatomic, strong) NSDate *todayDate;
@property (nonatomic, strong) NSString *todayString;

@property (nonatomic, strong) NSMutableDictionary *dicSummary;

@property (nonatomic, copy) NSArray *arrSummary;
@property (nonatomic, copy) NSArray *showDates;

@property (nonatomic, copy) void (^Update)();

@property (nonatomic, assign) BOOL hasLoadDB;

@property (nonatomic, strong) AILDSummary *localData;

@end

@implementation SummaryMgr

-(instancetype)init{
    self = [super init];
    if (self) {
        
        self.localData = [[AILDSummary alloc] init];
        [[TriggerEngine sharedInstance] addVisiter:self];
        
        self.dicSummary = [NSMutableDictionary dictionaryWithCapacity:30];
        self.todayDate = [NSDate date];
        self.todayString = [CALENDARMGR dateStrWithDate:self.todayDate format:@"yyyy-MM-dd"];
        self.type = Summary_Week;
        
        [self loadDatasFromDB];
        
    }
    return self;
}

-(void)needUpdate:(void (^)())update{
    self.Update = update;
}

-(void)triggerByAccountLogout{
    [self clearDatas];
}

-(void)clearDatas{
    [self.dicSummary removeAllObjects];
    self.hasLoadDB = NO;
}

-(void)loadDatasFromDB{
    NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:20];
    NSArray *daysData = [self.localData.dbSummary datasWithType:Summary_DB_Day];
    if (daysData && daysData.count > 0) {
        [tmp addObjectsFromArray:daysData];
    }else{
        self.localData.requestedMonth = NO;
    }
    NSArray *monthsData = [self.localData.dbSummary datasWithType:Summary_DB_Month];
    if (monthsData && monthsData.count > 0) {
        [tmp addObjectsFromArray:monthsData];
    }else{
        self.localData.requestedYear = NO;
    }
    for (NSDictionary *dic in tmp) {
        [self.dicSummary setObject:dic forKey:dic[@"searchDate"]];
    }
    self.hasLoadDB = YES;
    [self updateSummary];
}

-(SummaryModel *)modelWithType:(SummaryData_Type)type{
    SummaryModel *model = [[SummaryModel alloc] init];
    
    if ((![self.localData requestedWithType:self.type] && self.arrSummary.count == 0) || !self.hasLoadDB) {
        [self loadDatasFromDB];
    }
    
    model.dates = self.showDates;
    model.type = type;
    model.dateType = self.type;
    
    NSInteger sum = 0;
    NSInteger days = (self.localData.yearDriveDays + self.localData.days);
    
    switch (type) {
        case SummaryData_Mark:
        {
            NSMutableArray *arr = [NSMutableArray arrayWithArray:[self.arrSummary valueForKeyPath:K_AVGMARK]];
            if (self.type == Summary_Year) {
                [arr addObject:@(self.localData.AVGMARK)];
            }
            model.dataInfos = arr;
            model.title = @"得分";
            sum = [[arr valueForKeyPath:@"@sum.integerValue"] integerValue];
            CGFloat avg = [self avgNumWithNums:arr];
            model.avgNum = avg;
            model.avgInfo = [NSString stringWithFormat:@"日均得分:%zd(分)",(int)avg];
        }
            break;
        case SummaryData_OilPrice:
        {
            NSMutableArray *arr = [NSMutableArray arrayWithArray:[self.arrSummary valueForKeyPath:K_FUELPRICE]];
            if (self.type == Summary_Year) {
                [arr addObject:@(self.localData.FUELPRICE)];
            }
            model.dataInfos = arr;
            model.title = @"油费";
            CGFloat avg = [self avgNumWithNums:arr];
            model.avgNum = avg;
            CGFloat sumN = [[arr valueForKeyPath:@"@sum.floatValue"] floatValue];
            model.avgInfo = [NSString stringWithFormat:@"日均油费:%0.2f(元)",((self.type == Summary_Year)? (days != 0 ? sumN / days : 0) : avg)];
            sum = (int)sumN;
            model.sumNum = [NSString stringWithFormat:@"%0.2f",sumN];
            model.sumTitle = [NSString stringWithFormat:@"%@总油费(元)",[self stringSummary]];
        }
            break;
        case SummaryData_Mile:
        {
            NSMutableArray *arr = [NSMutableArray arrayWithArray:[self.arrSummary valueForKeyPath:K_TOTALMILES]];
            if (self.type == Summary_Year) {
                [arr addObject:@(self.localData.TOTALMILES)];
            }
            model.dataInfos = arr;
            model.title = @"里程";
            CGFloat avg = [self avgNumWithNums:arr];
            model.avgNum = avg;
            sum = [[arr valueForKeyPath:@"@sum.integerValue"] integerValue];
            model.avgInfo = [NSString stringWithFormat:@"日均里程:%zd(公里)",(int)((self.type == Summary_Year)? (days != 0 ? sum / days : 0) : avg)];
            model.sumNum = [NSString stringWithFormat:@"%zd",sum];
            model.sumTitle = [NSString stringWithFormat:@"%@总里程(公里)",[self stringSummary]];
        }
            break;
        case SummaryData_AvgOil:
        {
            NSArray *miles = [self.arrSummary valueForKeyPath:K_TOTALMILES];
            NSArray *oils = [self.arrSummary valueForKeyPath:K_TOTALFUEL];
            NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:miles.count];
            CGFloat mileNum = 0;
            CGFloat oilNum = 0;
            for (int i = 0; i < miles.count; i++) {
                CGFloat mile = [miles[i] floatValue];
                CGFloat oil = [oils[i] floatValue];
                CGFloat avgOil = (mile == 0 ? 0 :oil/mile*100);
                sum += avgOil;
                [tmp addObject:@(avgOil)];
                mileNum += mile;
                oilNum += oil;
            }
            if (self.type == Summary_Year) {
                [tmp addObject:@(self.localData.AVGOIL)];
                sum += self.localData.AVGOIL;
                mileNum += self.localData.TOTALMILES;
                oilNum += self.localData.TOTALFUEL;
            }
            model.dataInfos = tmp;
            model.title = @"百公里油耗";
            CGFloat avg = (mileNum == 0 ? 0 : (oilNum / mileNum * 100));
            model.avgNum = avg;
            model.avgInfo = [NSString stringWithFormat:@"日均油耗:%.02f(升)",avg];
        }
            break;
            
        default:
            break;
    }
    
    model.isNodata = (sum == 0);
    
    return model;
}

-(CGFloat)avgNumWithNums:(NSArray *)nums{
    __block NSInteger all = 0;
    __block CGFloat sum = 0;
    [nums enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        CGFloat num = [obj floatValue];
        if (num != 0) {
            all++;
            sum += num;
        }
    }];
    CGFloat avg = 0;

    avg = (all == 0 ? 0 : sum / all);
    return avg;
}

-(NSString *)stringSummary{
    switch (self.type) {
        case Summary_Month:
            return @"月";
            break;
        case Summary_Week:
            return @"周";
            break;
        case Summary_Year:
            return @"年";
            break;
        default:
            break;
    }
    return @"";
}

-(void)setType:(Summary_Type)type{
    if (_type != type) {
        _type = type;
        [self updateSummary];
    }
}

-(void)updateSummary{
    NSArray *keys = [self datesByType:self.type];
    
    NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:keys.count];
    
    for (int i = 0; i < keys.count; i++) {
        NSString *key = keys[i];
        NSDictionary *dic = self.dicSummary[key];
        if (dic) {
            [tmp addObject:dic];
        }else{
            [tmp addObject:[[SummaryReportModel alloc] init].modelDic];
        }
    }
    
    self.arrSummary = tmp;
    self.showDates = [self showDatesWithType:self.type];
    
    if (self.Update) {
        self.Update();
    }
    
    if (![self.localData requestedWithType:self.type]) {
        __weak __typeof(self) wself = self;
        [self updateDatesBy:self.type finish:^{
            [wself updateSummary];
        }];
    }
    [self createCurrentMonthSum];
}

-(NSArray *)showDatesWithType:(Summary_Type)type{
    NSInteger year = CALENDARMGR.year;
    NSInteger month = CALENDARMGR.month;
    NSInteger day = CALENDARMGR.day;
    
    day -= 1;
    if (day <= 0) {
        month -= 1;
        if (month < 1) {
            year -= 1;
            month = 12;
        }
        NSInteger max = [CALENDARMGR daysInYear:year month:month];
        day += max;
    }
    
    NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:7];
    
    switch (type) {
            
        case Summary_Month:
        {
            for (int i = 0; i < 5; i++) {
                NSMutableString *string = [NSMutableString stringWithCapacity:5];
                if (day-7 <= 0 || i == 4) {
                    [string appendFormat:@"%zd月%zd日",month,day];
                }else{
                    [string appendFormat:@"%zd",day];
                }
                [tmp addObject:string];
                
                day -= 7;
                if (day <= 0) {
                    month -= 1;
                    if (month < 1) {
                        year -= 1;
                        month = 12;
                    }
                    NSInteger max = [CALENDARMGR daysInYear:year month:month];
                    day += max;
                }
            }
        }
            break;
        case Summary_Week:
        {
            for (int i = 0; i < 7; i++) {
                NSMutableString *string = [NSMutableString stringWithCapacity:7];
                if (day-1 <= 0 || i == 6) {
                    [string appendFormat:@"%zd月%zd日",month,day];
                }else{
                    [string appendFormat:@"%zd",day];
                }
                [tmp addObject:string];
                
                day -= 1;
                if (day <= 0) {
                    month -= 1;
                    if (month < 1) {
                        year -= 1;
                        month = 12;
                    }
                    NSInteger max = [CALENDARMGR daysInYear:year month:month];
                    day += max;
                }
            }
        }
            break;
        case Summary_Year:
        {
            
            for (int i = 0; i < 4; i++) {
                NSMutableString *string = [NSMutableString stringWithCapacity:4];
                if (month-1 <= 0 || i == 3) {
                    [string appendFormat:@"%zd年",year];
                }
                [string appendFormat:@"%zd月",month];
                [tmp addObject:string];
                
                month -= 3;
                if (month <= 0) {
                    year -= 1;
                    month += 12;
                }
            }
        }
            break;
        default:
            break;
    }
    return [[tmp reverseObjectEnumerator] allObjects];
}

-(void)createCurrentMonthSum{
    NSArray *keys = [self keysCurrentMonth];
    
    NSInteger AVGMARK = 0;
    CGFloat FUELPRICE = 0;
    NSInteger TOTALMILES = 0;
    NSInteger AVGOIL = 0;
    CGFloat TOTALFUEL = 0;
    NSInteger num = 0;
    for (int i = 0; i < keys.count; i++) {
        NSString *key = keys[i];
        NSDictionary *dic = self.dicSummary[key];
        if (dic && [dic[@"DRIVING_COUNT"] integerValue] != 0) {
            num++;
            AVGMARK += [dic[K_AVGMARK] integerValue];
            FUELPRICE += [dic[K_FUELPRICE] floatValue];
            TOTALMILES += [dic[K_TOTALMILES] integerValue];
            TOTALFUEL += [dic[K_TOTALFUEL] floatValue];
        }
    }
    AVGMARK = (num == 0 ? 0 : AVGMARK / num);
    AVGOIL = TOTALMILES == 0 ? 0 : (TOTALFUEL / TOTALMILES * 100);
    self.localData.AVGMARK = AVGMARK;
    self.localData.TOTALFUEL = TOTALFUEL;
    self.localData.FUELPRICE = FUELPRICE;
    self.localData.TOTALMILES = TOTALMILES;
    self.localData.AVGOIL = AVGOIL;
    self.localData.days = num;
}

-(NSArray *)keysCurrentMonth{
    NSInteger year = CALENDARMGR.year;
    NSInteger month = CALENDARMGR.month;
    NSInteger day = CALENDARMGR.day;
    
    NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:10];
    for (int i = 1; i < day; i++) {
        [tmp addObject:[NSString stringWithFormat:@"%zd-%02zd-%02zd",year,month,i]];
    }
    return tmp;
}

-(NSArray *)datesByType:(Summary_Type)type{
    NSDate *startDate;
    NSDate *endDate;
    
    switch (type) {
        case Summary_Week:
            startDate = [CalendarMgr dateFromDate:self.todayDate beforeDays:7];
            endDate = [CalendarMgr dateFromDate:self.todayDate beforeDays:1];
            return [CALENDARMGR datesDayFrom:startDate to:endDate];
            break;
        case Summary_Month:
            startDate = [CalendarMgr dateFromDate:self.todayDate beforeDays:31];
            endDate = [CalendarMgr dateFromDate:self.todayDate beforeDays:1];
            return [CALENDARMGR datesDayFrom:startDate to:endDate];
            break;
        case Summary_Year:
            startDate = [CalendarMgr dateFromDate:self.todayDate beforeDays:330];
            endDate = [CalendarMgr dateFromDate:self.todayDate beforeDays:1];
            return [CALENDARMGR datesMonthFrom:startDate to:endDate];
            break;
            
        default:
            break;
    }
    return @[];
    
}

-(void)updateDatesBy:(Summary_Type)type finish:(void(^)())finish{
    __weak __typeof(self) wself = self;
    if (type == Summary_Week) {
        type = Summary_Month;
    }

    [[NetHome getSummaryInfoWithType:type time:self.todayString] requestSuccess:^(id JSON) {
        Summary_Type dbType;
        switch (type) {
            case Summary_Month:
                dbType = Summary_DB_Day;
                break;
            case Summary_Week:
                dbType = Summary_DB_Day;
                break;
            case Summary_Year:
                dbType = Summary_DB_Month;
                break;
                
            default:
                break;
        }
        NSArray *datas = JSON[@"infolist"];
        
        [wself.localData setRequestedOKWithType:wself.type];
        
        NSMutableArray *tmp = [NSMutableArray arrayWithCapacity:datas.count];
        BOOL hasGetDays = NO;
        for (NSDictionary *dic in datas) {
            if (wself.type == Summary_Year && !hasGetDays) {
                wself.localData.yearDriveDays = [dic[@"DRIVING_DAYCOUNT"] integerValue];
                hasGetDays = YES;
            }
            SummaryReportModel *model = [[SummaryReportModel alloc] init];
            [model fillModelWithDic:dic];
            model.summaryType = dbType;
            [tmp addObject:model.jsonObjectDic];
            
            [wself.dicSummary setObject:model.modelDic forKey:model.searchDate];
        }
        
        [wself.localData.dbSummary addDatas:tmp];
        
        if (finish) {
            finish();
        }
        
    } failure:^(id JSON) {
        
    }];
}

@end